package com.ytjj.qmyx.mall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.GsonBuilder;
import com.ytjj.common.cmpp.OperatorJudgeUtil;
import com.ytjj.common.exception.GlobalExceptionHandler;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.OrderUtils;
import com.ytjj.qmyx.mall.mapper.OrdersInfoMapper;
import com.ytjj.qmyx.mall.mapper.RechargeDao;
import com.ytjj.qmyx.mall.model.request.RechargeCallbackRequest;
import com.ytjj.qmyx.mall.model.vo.RechargeVO;
import com.ytjj.qmyx.mall.service.RechargeService;
import com.ytjj.qmyx.mall.service.WxService;
import com.ytjj.qmyx.mall.utils.HFSoowareUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 *
 *  *
 **/
@Slf4j
@Service
@RefreshScope
public class RechargeServiceImpl implements RechargeService {

    /**
     * 渠道标识
     */
    @Value("${recharge.adapterId}")
    private String adapterId;

    /**
     * 加密key
     */
    @Value("${recharge.key}")
    private String key;

    /**
     * 加密iv
     */
    @Value("${recharge.iv}")
    private String iv;

    /**
     * 回调地址
     */
    @Value("${recharge.notifyUrl}")
    private String notifyUrl;


    @Resource
    private RechargeDao rechargeDao;

    @Autowired
    private Map<String, WxService> wxServiceMap;
    //手机充值退款时 是否调用第三分接口验证充值状态 1-不调用 0-调用
    @Value("${phone.recharge.back.switch:1}")
    private Integer phoneRechargeBackSwitch;


    @Override
    public void mqRecharge(String orderNo, String operators){
        log.info("===充值信息==={}", orderNo);
        RechargeVO rechargeVO = rechargeDao.findByOrderNo(orderNo);
        //找不到订单获取微信未支付成功不做处理
        if(rechargeVO == null || rechargeVO.getStatus() != 3) {
            return;
        }
        if(StringUtils.isEmpty(operators) && StringUtils.isNotEmpty(rechargeVO.getOperators())){
            operators = rechargeVO.getOperators();
        }

        Integer rechargeStatus = rechargeVO.getRechargeStatus();
        log.info("===rechargeVO==={}", rechargeVO);
        //充值中 充值失败的订单走查询结果 更新状态
        if(rechargeStatus != null){
            //2充值中 3充值失败
            if(rechargeStatus.equals(2) ||  rechargeStatus.equals(3)) {
                RechargeCallbackRequest rechargeCallbackRequest = queryOrder(rechargeVO.getOrderNo());
                log.info("===rechargeCallbackResponse==={}", rechargeCallbackRequest);
                //查询为充值失败
                String resRechargeStatus;
                if(null == rechargeCallbackRequest){
                    resRechargeStatus = "E001";
                }else{
                    resRechargeStatus = rechargeCallbackRequest.getRespCode();
                }

                if("0001".equals(resRechargeStatus)) {//充值中
                    rechargeVO.setRechargeStatus(2);
                }else if("0000".equals(resRechargeStatus)) {//充值成功
                    rechargeVO.setRechargeStatus(1);
                }else if("E001".equals(resRechargeStatus)){//网络或其他问题
                    rechargeVO.setRechargeStatus(2);
                }else {//其他为失败
                    rechargeVO.setRechargeStatus(3);
                }

                if(rechargeVO.getRechargeStatus().equals(3) && !rechargeVO.getGiveFlag().equals(1)){
                    //判断是充值订单 还是返话费订单 返话费订单不能走退款
                    String returnCode = OrderUtils.getReturnCode(null);
                    String refundMsg = rechargeFail(rechargeVO.getType(),orderNo, returnCode, rechargeVO.getDenomination(), "充值失败！");
                    if(refundMsg != null) {
                        rechargeVO.setStatus(4);
                        rechargeVO.setRechargeStatus(4);
                        rechargeVO.setRefundNo(returnCode);
                        rechargeVO.setRefundMsg(refundMsg);
                    }

                }
                if(null != rechargeCallbackRequest){
                    rechargeVO.setPlatformCallback(JSONObject.toJSONString(rechargeCallbackRequest));
                }
                rechargeVO.setPlatformCallbackTime(new Date());
                rechargeDao.updateCallbackStatus(rechargeVO);
                rechargeDao.updateStreamStatus(rechargeVO);
                updateOrderInfoRechargeStatus(rechargeVO);//todo 这个没有发现可用之处 uuid主要就是这里用
                //更新订单表的recharge_status
                if (rechargeVO.getRechargeStatus().equals(1) && rechargeVO.getGiveFlag().equals(1)) {
                    log.info("===更新订单赠送话费状态==={}", orderNo);
                    rechargeDao.updateOrderRechargeStatus(orderNo);
                }
                //todo 多少次后设置为充值失败呢 暂时走线下方式，从充值平台查询结果
            }
        }

        //还没充值的 走充值
        if(rechargeStatus == null) {
            log.info("===enter recharge==={}", rechargeVO.getOrderNo());
            RechargeVO recharge = recharge(rechargeVO.getPhone(), rechargeVO.getOrderNo(), rechargeVO.getDenomination()+"", operators);
            log.info("===recharge response==={}", recharge);
            recharge.setId(rechargeVO.getId());
            recharge.setOrderNo(orderNo);
            recharge.setUuid(rechargeVO.getUuid());
            recharge.setType(rechargeVO.getType());
            rechargeDao.saveStream(recharge);
            rechargeDao.updateStatus(recharge);
            updateOrderInfoRechargeStatus(recharge);
        }

    }

    public void updateOrderInfoRechargeStatus(RechargeVO recharge) {
        try{
            if(!recharge.getType().equals("RECHARGE_COUPON")){
                return;
            }
            Integer rec= recharge.getRechargeStatus();
            if(rec.equals(2)){
                return;
            }
            BigDecimal status = null;
            if(rec.equals(1)){
                status = new BigDecimal(-1);
            }
            if(rec.equals(3) || rec.equals(4)){
                status = new BigDecimal(-2);
            }
            rechargeDao.updateOrderInfo(Integer.parseInt(recharge.getUuid()),status);
        }catch (Exception e) {
            log.error("更新充值订单状态失败",e);
        }
    }

    /**
     * 充值失败 微信退款
     */
    public String rechargeFail(String type,String orderNo,String refundNo,Integer amount,String desc) {
        //充值优惠券的不做退款处理
        if(!type.equals("RECHARGE_COUPON")){
            try {
                return  wxServiceMap.get(type).refundRecharge(orderNo, refundNo, amount, amount, desc).toString();
            } catch (Exception e) {
                log.error(GlobalExceptionHandler.getExceptionToString(e));
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public String rechargeFailByRpc(String type, String orderNo, String refundNo, Integer amount, String desc) {
        try {
            log.info("===手机充值退款==={},{},{},{},{}", type, orderNo, refundNo, amount, desc);
//            RechargeCallbackRequest rechargeCallbackRequest = queryOrder(orderNo);
            RechargeCallbackRequest rechargeCallbackRequest = new RechargeCallbackRequest();
            if (phoneRechargeBackSwitch.equals(1)) {
                rechargeCallbackRequest.setRespCode("0002");
            }else {
                rechargeCallbackRequest = queryOrder(orderNo);
            }
            log.info("===rechargeCallbackRequest==={}", rechargeCallbackRequest);
            //查询为充值失败
            String resRechargeStatus;
            if(null == rechargeCallbackRequest){
                resRechargeStatus = "E001";
            }else{
                resRechargeStatus = rechargeCallbackRequest.getRespCode();
            }
            if("0001".equals(resRechargeStatus)) {//充值中
                return "充值中，不能发起退款！";
            }else if("0000".equals(resRechargeStatus)) {//充值成功
                return "充值成功，不能发起退款！";
            }else if("E001".equals(resRechargeStatus)){//网络或其他问题
                return "充值中，不能发起退款！";
            }
            Map response = wxServiceMap.get(type).refundRecharge(orderNo, refundNo, amount, amount, desc);
            log.info("===手机充值退款，响应结果：{}", response);
            if (null == response) {
                return "退款失败";
            }
            if ("SUCCESS".equals(response.get("return_code"))) {
                return "退款成功";
            }else {
                return "退款失败";
            }

        } catch (Exception e) {
            log.error(GlobalExceptionHandler.getExceptionToString(e));
        }
        return "退款失败";
    }

    @Override
    public RechargeVO recharge(String phone, String orderNo, String amount, String operators) {
        //返回结果
        RechargeVO rechargeVO = new RechargeVO();
        rechargeVO.setRechargeStatus(3);
        Map<String, Object> headerMap = new HashMap<String, Object>();
        headerMap.put("adapterId", adapterId);
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("orderId", orderNo);
        bodyMap.put("mobile", phone);
        String productId="";
        BigDecimal rechargeAmount=new BigDecimal(amount);
        int intAmount=rechargeAmount.divide(new BigDecimal(100)).intValue();
        //根据手机号获取运营商
        operators = checkOperator(phone);

        if("01".equals(operators)){//中国移动
            productId="MOBILE-"+intAmount;
        }else if("02".equals(operators)){//中国联通
            productId="UNICOM-"+intAmount;
        }else if("03".equals(operators)){//中国电信
            productId="TELECOM-"+intAmount;
        }else{
            log.error("不支持的运营商,{}",operators);
            rechargeVO.setDesc("不支持的运营商");
            return rechargeVO;
        }
        bodyMap.put("productId", productId);
        bodyMap.put("ackUrl", notifyUrl);//这个地方要填回调地址
        bodyMap.put("timestamp",System.currentTimeMillis());
        String orderUrl = "http://hf.sooware.com:9090/huafei/std/order";
        String response = "";

        try {
            rechargeVO.setPlatformParameter(HFSoowareUtils.encoding(headerMap,bodyMap,key,iv));
            rechargeVO.setPlatformTime(String.valueOf(System.currentTimeMillis()));
            response = HFSoowareUtils.post(orderUrl, headerMap, bodyMap, key, iv);
            log.info("单号:{},充值响应:{}",orderNo,response);
        }catch (Exception e){
            log.error("单号：{},充值错误",orderNo);
        }
        rechargeVO.setPlatformResult(response);
        log.info("充值请求参数：\n{}", rechargeVO.getPlatformParameter());
        log.info("充值请求结果：\n{}", response);
        if (response != null) {
            JSONObject resultJson = JSONObject.parseObject(response);
            String respCode = resultJson.getString("respCode");
            if (respCode.equals("0000")) {
                rechargeVO.setRechargeStatus(2);
            }else{
                rechargeVO.setDesc(resultJson.getString("respDesc"));
            }
        }
        return rechargeVO;
    }

    /**
     * 根据手机号获取运营商
     * @param phone
     * @return
     */
    private String checkOperator(String phone) {
        String result = null;
        String businessOperator = OperatorJudgeUtil.checkOperator(phone);
        switch (businessOperator) {
            case "mobile":
                result = "01";
                break;
            case "unicom":
                result = "02";
                break;
            case "telecom":
                result = "03";
                break;
            default:
                result = "unknown";
                break;
        }
        return result;
    }

    @Override
    public void callback(RechargeCallbackRequest request) {
        String req = JSONObject.toJSONString(request);
        log.info("充值回调结果》》》》》\n{}",req);
    }


    @Override
    public String getBalance() {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("adapterId", adapterId);
        String strUrl = "http://hf.sooware.com:9090/huafei/std/balance";
        String json = new GsonBuilder().create().toJson(dataMap);
        String response = "";
        try{
            response = HFSoowareUtils.post(strUrl, json);
            log.info("余额查询:{}",response);
        }catch (Exception e){
            log.error("余额查询");
        }
        if(response != null) {
            JSONObject resJson = JSONObject.parseObject(response);
            log.info("商户余额结果-> \n{}",response);
            if(resJson.getString("respCode").equals("0000")) {
                return resJson.getString("balance");
            }
        }
        return "0";
    }


    @Override
    public RechargeCallbackRequest queryOrder(String orderNo) {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("adapterId", adapterId);
        List<String> orders = new ArrayList<>();
        orders.add(orderNo);
        dataMap.put("orderIds", orders.toArray());
        String strUrl = "http://hf.sooware.com:9090/huafei/std/status";
        String json = new GsonBuilder().create().toJson(dataMap);
        String response ="";
        try{
            response = HFSoowareUtils.post(strUrl, json);
            log.info("单号:{},充值查询:{}",orderNo,response);
        }catch (Exception e){
            log.info("==={}", e);
            log.error("单号：{},充值查询错误",orderNo);
        }

        if(StringUtils.isNotBlank(response)) {
            log.info("查询订单结果-> \n{}",response);
            JSONObject resJson = JSONObject.parseObject(response);
            RechargeCallbackRequest data = new RechargeCallbackRequest();
            data.setOrderId(orderNo);
            data.setRespDesc(resJson.getString("respDesc"));
            if("0000".equals(resJson.getString("respCode"))) {
                JSONArray dataArray = resJson.getJSONArray("statusList");
                if (dataArray != null && dataArray.size() > 0) {
                    data.setRespCode(dataArray.getJSONObject(0).getString("status"));
                }else{
                    data.setRespCode("E02");
                }
            }else{
                data.setRespCode(resJson.getString("respCode"));
            }
            return data;
        }
        return null;
    }

    @Override
    public void testMq() {
//        PrepaidRefillDto prepaidRefillDto = new PrepaidRefillDto();
//        prepaidRefillDto.setOrderNo("P20201223212551777798");
//        System.out.println("----发送mq------");
//        rabbitTemplate.convertAndSend(QueueConstants.RECHARGE_QUEUE,prepaidRefillDto);
        System.out.println("----------");
//        AliyunSmsUtil.sendSms("19902433508",1,"");
//        SmsDto smsDto = new SmsDto("19902433508",1,"");
//        rabbitTemplate.convertAndSend(QueueConstants.SMS_QUEUE,smsDto);
//        System.out.println("----------");

    }

}
